#include <iostream>
#include <cstdio>
#include <string>
#include <vector>
#include <queue>
#include <algorithm>

#define FOR(i,a,n) for(int i=a,_n(n);i<_n;++i)
#define REP(i,n) FOR(i,0,n)

using namespace std;

bool mp[110][110];
vector<int> s;
int ring;
int toDag[110];
int low[110],ord[110],cnt,gn;

class Graph
{
    public:
  struct Edge
  {
    int vs,vt;
    Edge* next;
    void Set(int a,int b,Edge* nt)
    {
        vs = a,vt = b,next = nt;
    }
  };
  int vn,arcn;
  Edge *edge,**head;
  Graph(int n,int m)
  {
    head = new Edge*[(vn=n)+10];
    edge = new Edge[m+10];
    arcn = 0;
    fill(head,head+vn+10,(Edge*)NULL);
  }
  void AddArc(int vs,int vt)
  {
    edge[arcn].Set(vs,vt,head[vs]);
    head[vs] = &edge[arcn++];
  }
  void AddEdge(int v1,int v2)
  {
    AddArc(v1,v2);
    AddArc(v2,v1);
  }
  void Tarjan(int pos,int pre)
  {
   // printf("tarjan %d->%d\n",pre,pos);
    ord[pos] = low[pos] = cnt++;
    s.push_back(pos);
    for(Edge* ep=head[pos];ep;ep=ep->next)
    {
    if(ord[ep->vt]==-1)
    {
      //   printf("to %d\n",ep->vt);
        Tarjan(ep->vt,pos);
        if(low[ep->vt]<low[pos]) low[pos] = low[ep->vt];
    }
    else if(ep->vt!=pre&&ord[ep->vt]<low[pos]) low[pos] = ord[ep->vt];
    }
    //printf("%d: low=%d ord=%d\n",pos,low[pos],ord[pos]);
    if(low[pos]==ord[pos])
    {
        int ct = 0;
        while(true)
        {
            int t = s.back();s.pop_back();
           // printf("toDag[%d]=%d\n",t,gn);
            toDag[t] = gn;
            ct++;
            if(t==pos) break;
        }
        if(ct>1) ring++;
        gn++;
    }
  }
  void GetAns()
  {
    REP(i,vn+1) ord[i]=-1;
    cnt = 0;gn = 0;ring=0;
    Tarjan(1,-1);
    if(cnt<vn||ring!=1) puts("NO");
    else
    {
        int edct = 0;
        int ringEdct = 0;
        REP(i,arcn)
        {
            Edge* ep = edge+i;
            int vs = toDag[ep->vs];
            int vt = toDag[ep->vt];
            if(vs==vt)
            {
           //     printf("%d<->%d\n",ep->vs,ep->vt);
                ringEdct++;
            }
            else if(!mp[vs][vt])
            {
                edct++;
                mp[vs][vt] = mp[vt][vs] = true;
            }
        }
        ringEdct>>=1;
      //  printf("%d %d\n",ringEdct,vn-gn+1);
        if(edct!=gn-1||ringEdct!=vn-gn+1) puts("NO");
        else puts("FHTAGN!");
    }
  }
};

int main()
{
    int n,m;
    cin>>n>>m;
    Graph g(n,m*2);
    REP(i,m)
    {
        int a,b;
        scanf("%d%d",&a,&b);
        g.AddEdge(a,b);
    }
    g.GetAns();
	return 0;
}
/*
6 6
6 3
6 4
5 1
2 5
1 4
5 4
*/
